<template>
  <el-upload
      ref="uploadFile"
      v-loading="uploadImage.loading"
      :headers="uploadImage.headers"
      :class="listLengthTag >= limit?'hide_box':''"
      action="#"
      list-type="picture-card"
      :on-preview="handlePreview"
      :before-upload="beforeUpload"
      :on-exceed="handleExceed"
      :on-remove="handleRemove"
      :on-error="handleError"
      :limit="limit"
      :multiple="multiple"
      :drag="drag"
      :file-list="picList"
      :http-request="uploadSubmit"
      :accept="accept">
    <i class="el-icon-plus"></i>
    <image-viewer v-if="uploadImage.viewer.visible" :urlList="uploadImage.viewer.picList" :on-close="onClose"
                  :z-index="2100"/>
  </el-upload>
</template>


<script>
import {getToken, getTokenKey} from "@/utils/auth";
import ImageViewer from "element-ui/packages/image/src/image-viewer";

export default {
  name: 'UploadImage',
  components: {
    ImageViewer,
  },
  props: {
    picList: {
      type: Array,
      default: () => []
    },
    listLengthTag: {//判断是否达到最大，达到最大隐藏最后一个上传框
      type: Number,
      default: 0
    },
    limit: {
      type: Number,
      default: 1
    },
    accept: {
      type: String,
      default: '.jpg,.jpeg,.png,.JPG,.JPEG,.PNG'
    },
    drag: {
      type: Boolean,
      default: false
    },
    multiple: {
      type: Boolean,
      default: true
    },
    action: {
      type: String,
      default: process.env.VUE_APP_BASE_API + process.env.VUE_APP_FILE + "/storage/upload", // 从环境变量中获取基础API路径，并在组件的数据对象中定义它
    },
    fileSize: {
      type: Number,
      default: 10 //单个文件大小单位（M)
    }
  },
  data() {
    return {
      uploadImage: {
        headers: {[getTokenKey()]: "Bearer " + getToken()},
        loading: false,
        picList2: [],
        viewer: {
          picList: [],
          visible: false
        }
      },
    }
  },
  methods: {
    beforeUpload(file) {
      const size = file.size / 1024 / 1024 < this.fileSize;
      if (!size) {
        this.$message.warning(`文件大小超出${this.fileSize}M`);
        return false;
      }
      const fileTypes1 = file.name
          .substring(file.name.lastIndexOf("."))
          .toLowerCase();
      let acceptArr = this.accept.split(",");

      const isPic = acceptArr.indexOf(fileTypes1) !== -1; // 是否指定类型
      if (!isPic) {
        this.$message.warning(`文件类型错误，仅支持[${this.accept}]文件类型`);
        return false;
      }
      return true;
    },
    // //文件状态改变时触发
    // handleChange(file, fileList) {
    //   this.$emit('update:picList', fileList)
    //   this.$emit('update:listLengthTag', fileList.length)
    //   this.uploadImage.loading = false
    // },
    //预览
    handlePreview(file) {
      //把用户点击的那张图片放到第一个位置,这样打开就能看到自己点击的那张图片
      this.uploadImage.viewer.picList = this.picList.filter(e => e.url !== file.url).map(e => e.url);
      this.uploadImage.viewer.picList.unshift(file.url)
      // //设置 图片查看器 进行显示
      this.uploadImage.viewer.visible = true;
    },
    //关闭预览
    onClose() {
      this.uploadImage.viewer.visible = false;
    },
    //删除已经上传的
    handleRemove(file, fileList) {
      this.$emit('update:picList', fileList)
      this.$emit('update:listLengthTag', fileList.length)
    },
    //限制上传文件的个数提示-隐藏了上传框按逻辑这里不会触发
    handleExceed(files, fileList) {
      this.$message.warning(`当前限制选择 ${this.limit} 个文件，本次选择了 ${files.length} 个文件，共选择了 ${files.length + fileList.length} 个文件`);
    },
    handleError(err) {
      this.$message.error(err.message || '上传失败');
      this.uploadImage.loading = false;

    },
    async uploadSubmit({file}) {
      try {
        this.uploadImage.loading = true;
        // 1. 获取签名URL
        const {data: {url, headers}} = await this.$axiosFile({
          url: '/fileMetadataInfo/upload/getSignUrl',
          method: 'get',
          params: {fileName: file.name}
        });

        // 2. 上传文件到OSS
        await fetch(url, {
          method: 'PUT',
          headers,
          body: file
        });
        // 3. 更新文件列表
        let newFile = {
          name: file.name,
          url: url.split('?')[0],
          uid: file.uid
        };
        let newPicList = [...this.picList, newFile]
        this.$emit('update:picList', newPicList);
        this.$emit('update:listLengthTag', newPicList.length)
      } catch (error) {
        this.$message.error('上传失败');
      } finally {
        this.uploadImage.loading = false;
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.hide_box {
  ::v-deep.el-upload--picture-card {
    display: none;
  }
}

::v-deep .el-list-leave-active {
  transition: none;
}

::v-deep .el-list-leave-to {
  transition: none;
}
</style>
